#include "server.hpp"

class TcpServer
{
private:
    uint64_t _next_id; // 下一个连接的id（自动增长）
    int _port;         // 端口号
    int _timeout = 0;  // 这是⾮活跃连接的统计时间---多⻓时间⽆通信就是⾮活跃连

    bool _enable_inactive_release; // 是否开启⾮活跃连接的释放

    EventLoop _baseloop;  // 这是主线程的EventLoop对象，负责监听事件的处理
    LoopThreadPool _pool; // 这是从属EventLoop线程池
    Acceptor _acceptor;
    std::unordered_map<uint64_t, PtrConnection> _conns; // 保存管理所有连接对应的shared_ptr对象

    using ConnectedCallback = std::function<void(const PtrConnection &)>;
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>;
    using ClosedCallback = std::function<void(const PtrConnection &)>;
    using AnyEventCallback = std::function<void(const PtrConnection &)>;
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    void RunAfterInLoop(const Functor &cb, int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id, delay, cb);
    }

    // 为新连接构建一个姓的Connection对象
    void NewConnection(int fd)
    {
        _next_id++;
        PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        // 启动⾮活跃超时销毁
        if (_enable_inactive_release)
            conn->EnableInactiveRelease(_timeout);
        conn->Established(); // 就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }

    void RemoveConnectionInLoop(const PtrConnection &conn) // diff
    {
        if (_conns.find(conn->Id()) != _conns.end())
        {
            _conns.erase(conn->Id());
        }
    }
    // 从管理Connection的_conns中移除连接信息
    void RemoveConnection(const PtrConnection &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }

public:
    TcpServer(int port):_port(port),_next_id(0),_enable_inactive_release(false),_acceptor(&_baseloop,_port),_pool(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
        _acceptor.Listen();//将监听套接字挂到baseloop上
    }

    void SetThreadCount(int count)
    {
        _pool.SetThreadCount(count);
    }

    void SetConnectedCallback(const ConnectedCallback &cb)
    {
        _connected_callback = cb;
    }

    void SetMessageCallback(const MessageCallback &cb)
    {
        _message_callback = cb;
    }

    void SetClosedCallback(const ClosedCallback &cb)
    {
        _closed_callback = cb;
    }

    void SetAnyEventCallback(const AnyEventCallback &cb)
    {
        _event_callback = cb;
    }
    void EnableInactiveRelease(int timeout)
    {
        _enable_inactive_release = true;
        _timeout = timeout;
    }

    // 用于在线程中添加一个定时任务
    void RunAfter(const Functor &cb, int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, cb, delay));
    }
    void Start()
    {
        _pool.Create();
        _baseloop.Start();
    }

};